<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // 本质上，这种写法属于“模式匹配”，只要等号两边的模式相同，左边的变量就会被赋予对应的值。

    // 数组解构 => 对应下标解构
    // 对象解构 => 对应键名解构  => 如果需要对 对象中的属性进行二次解构,需要对应键名解构键值

    var zhang = { name: "张三", age: 18, height: "177cm", weight: "70kg" }

    // 完全解构
    // var {name,age,height,weight} = { name: "张三", age: 18, height: "177cm", weight: "70kg" };
    // console.log(name,age,height,weight);

    // 不完全解构
    // var {age, name} = { name: "张三", age: 18, height: "177cm", weight: "70kg" };
    // console.log(name,age);


    // 解构不成功  => undefined
    // var {name,age,height,weight,sex} = { name: "张三", age: 18, height: "177cm", weight: "70kg" };
    // console.log(name,age,height,weight,sex);

    // 解构过程中可以设置默认值
    // var {name,age,height,weight,sex = "保密"} = { name: "张三", age: 18, height: "177cm", weight: "70kg" };
    // console.log(name,age,height,weight,sex);


    // 对象解构需要注意的问题:

    // var {foo} = 1;    // toString()  toFixed()
    // var {foo} = "hello";    
    // var {foo} = true;    
    // console.log(foo);  // undefined => 对象中没有此属性

    // var {toString} = 1;    
    // var {toString} = "hello";    
    // var {toString} = true;    
    // console.log(toString);

    // 不能对象 null 和 undefined进行解构 !!
    // var {foo} = null;
    // console.log(foo);


    // 解构的高级  
    // 1.  Rest参数 => 配合扩展运算符实现Rest参数(合并剩余参数)
    // ... info =>  height: "177cm", weight: "70kg"  反推 info = {height: "177cm", weight: "70kg"}
    var { name, age, ...info } = { name: "张三", age: 18, height: "177cm", weight: "70kg" };
    console.log(name, age, info);

    // 报错: Rest element must be last element
    // var {name, ...info,age } = { name: "张三", age: 18, height: "177cm", weight: "70kg" };
    // console.log(name,age,info);

    // 对象解构只需对应键名解构
    // var {name,height, ...info } = { name: "张三", age: 18, height: "177cm", weight: "70kg" };
    // console.log(name,height,info);


    // 2. 复杂数据解构
    var zhang = { name: "张三", age: 18, info: { height: "177cm", weight: "70kg" }, grade: [55, 66, 77] };

    // 拆分:  low
    // var {name,age,info,grade} =  { name: "张三", age: 18, info:{ height: "177cm", weight: "70kg"},grade:[55,66,77] };
    // console.log(name,age,info,grade); // info => { height: "177cm", weight: "70kg"}  grade=>[55,66,77]

    // var {height,weight} = info;
    // console.log(height,weight);

    // var [ch,mh,eh] = grade;
    // console.log(ch,mh,eh);

    // 直接解构  => 如果需要对 对象中的属性进行二次解构,需要对应键名解构键值
    // var {name,age,info:info,grade} =  { name: "张三", age: 18, info:{ height: "177cm", weight: "70kg"},grade:[55,66,77] };
    // var { name, age, info: { height, weight } = info, grade: [ch, mh, eh] = grade } = { name: "张三", age: 18, info: { height: "177cm", weight: "70kg" }, grade: [55, 66, 77] };
    // var { name, age, info: { height, weight }, grade: [ch, mh, eh] } = { name: "张三", age: 18, info: { height: "177cm", weight: "70kg" }, grade: [55, 66, 77] };
    // console.log(name, age, height, weight, ch, mh, eh); // info => { height: "177cm", weight: "70kg"}  grade=>[55,66,77]


    var { name, age, info: { height, weight }, grade: [ch, mh, eh] } = { name: "张三", age: 18, info: { height: "177cm", weight: "70kg" }, grade: [55, 66, 77] };
    console.log(name, age, height, weight, ch, mh, eh);


    // var list = [1,2,[3,4,[5,6]]];
    // var [a,b,[c,d,[e,f]]] = list;
  
    // 对象解构技巧:
    // 1. 如果是对象的根属性 => 可以直接对应键名解构
    // 2. 如果对 对象的某个属性的进行二次解构,需要对应键名解构键值

    // 解构练习:
    let obj = {
        p: [
            'Hello',
            { y: 'World' }
        ]
    };
    // var y = obj.p[1].y

    // var {p} = obj;
    // var {p:[x,{y}]} = obj;
    // console.log(x,y);



    const node = {
        loc: {
            start: {
                line: 1,
                column: 5
            }
        }
    };

    // var line = node.loc.start.line;

    // var {loc} = node;
    // var {loc:{start:{line,column}}} = node;








</script>

</html>